package gbench.sandbox.matrix.img;

import java.util.Arrays;

import org.junit.jupiter.api.Test;

import gbench.common.tree.LittleTree;
import gbench.common.tree.LittleTree.Elem;
import gbench.sandbox.matrix.img.util.MatlibCanvas.NVec;
import gbench.sandbox.matrix.img.util.MatlibCanvas.Range;
import gbench.sandbox.matrix.img.util.MatlibCanvas.XVec;

/**
 * 简单的数学运算
 * @author gbench
 *
 */
public class JunitVec {
    
    @Test
    public void foo() {
        final var rng = Range.of2(1,10);
        final var nvec = NVec.of(rng);
        final var nvec1 = NVec.of(rng.reverse()); // 由于rng 是包含状态所以他的start是11而不是10
        System.out.println("nvec:"+nvec);
        System.out.println("nvec1(由于rng 是包含状态所以他的start是11而不是10):"+nvec1);
        System.out.println("add(_1,_1):"+nvec.add(nvec));
        System.out.println("sub(_1,_1):"+nvec.sub(nvec));
        System.out.println("sub2(_1,_1*3):"+nvec.sub2(nvec.mul(NVec.of(3))));
        System.out.println("mul(_1,_1):"+nvec.mul(nvec));
        System.out.println("div(_1,_1):"+nvec.div(nvec));
        System.out.println("div2(_1*2,_1):"+nvec.mul(NVec.of(2)).div2(nvec));
        System.out.println("div(_1,_1*2)  循环补位:"+nvec.div(nvec.mul(2)));
        
        System.out.println("var:"+nvec.var());
        System.out.println("sd:"+nvec.sd());
        System.out.println("sum:"+nvec.sum());
        System.out.println("dot:"+nvec.dot(nvec));
        System.out.println("dot:"+nvec.add(nvec));
        System.out.println("product:"+nvec.product());
        System.out.println("matrix:\n"+nvec.matrix());
        System.out.println("matrix.transpose:\n"+nvec.matrix(e->e.transpose()));
    }

    @Test
    public void permute() {
        
        Range.cph(Range.of2(1, 2), Range.of2(3, 4)).forEach(e -> {
            System.out.println(e);
        });
        
        System.out.println();
        final var rng = Range.of(10);
        Range.cphx(e->{
            System.out.println(e);
        },rng,rng,rng);
    }
    
    /**
     * Permutation cph 性能
     */
    @Test
    public void range_permute() {
        final var p = new Range.Permutation<String>(ranges);
        final var last = LittleTree.timeit(()->p.permute(Arrays::deepToString, e -> {
            //System.out.println(e);
        }));
        System.err.println("Range.Permutation:10^"+ranges.length+"量级 lasts for "+last/1000+" ms");
    }

    /**
     * 千万数据 Elem.cph:7 lasts for 0.29846429999999996 ms
     */
    @Test
    public void elem_cph() {
        
        final var last = LittleTree.timeit(()->Elem.cph(ranges).forEach(e -> {
            //System.out.println(e);
        }));
        System.err.println("Elem.cph:10^"+ranges.length+"量级 lasts for "+last/1000+" ms");
    }

    /**
     * 千万数据直接奔溃
     */
    @Test
    public void littletree_cph() {
        
        final var last = LittleTree.timeit(()->LittleTree.cph((Object[][])ranges).forEach(e -> {
            //System.out.println(e);
        }));
        System.err.println("LittleTree.cph:10^"+ranges.length+"量级 lasts for "+last/1000+" ms");
    }
    
    @Test
    public void total() {
        this.range_permute();
        this.elem_cph();
        this.littletree_cph();
    }
    
    /**
     * 向量的列顺序编排成矩阵
     */
    @Test
    public void flatten() {
        final var vec = NVec.of(Range.of(27));
        final var oo = vec.reshape(3,3,3);
        final var xvec = XVec.of(oo);
        
        System.out.println("reshape后的数据"+oo);
        System.out.println("没有flat的向量结果:"+xvec);
        System.out.println("flat 扁平化的结果 :\n"+XVec.flat(oo,Double.class));
        
        // 修改了  oo[2,1]为一个二维数组,由于起先的oo[2,1]是一个三维数组.所以最造成缺少一个数据23
        XVec.write(oo, new Double[] {-21d,-22d}, 2,1);// 写入一个小一号的数组,为reshape构造麻烦
        XVec.write(oo, 100d, 2,2,1);// 修改最后一个元素为100
        XVec.flattenS(oo,Double.class).forEach(ivp->{
            System.out.println(ivp);
        });
        
        System.out.println("遍历一个普通对象,index为空数组");
        XVec.flattenS(3,Integer.class).forEach(ivp->{
            System.out.println(ivp);
        });
    }

    final String[] ss = "0123456789".split("");
    final String[][] ranges = new String[][] { ss, ss, ss, ss, ss, ss, ss };

}
